package com.hui.auth.config.shiro.session;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redis持久层工具
 * Created by LiaoYunHui on 2017/9/11.
 * <p>
 * EnterpriseCacheSessionDAO会在本地和redis服务器同时维护session
 * 注意，本地缓存通过EhCache实现，失效时间一定要远小于Redis失效时间，这样本地失效后，(相对来说更消耗内存资源)
 * 会访问Redis读取，并重新设置Redis上会话数据的过期时间。
 * <p>
 * MemorySessionDAO只在本地服务器上维护session，shiro默认的sessionDao
 */
@Component
@SuppressWarnings({"rawtypes", "unchecked"})//用于消除警告
public class CustomSessionRedisDao extends EnterpriseCacheSessionDAO {
    @Resource
    private RedisTemplate template;//获得redis字符串操作对象

    // 创建session，保存到数据库
    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        this.assignSessionId(session, sessionId);
        template.opsForValue().set(session.getId(), session, session.getTimeout(), TimeUnit.MILLISECONDS);
        return sessionId;
    }

    // 获取session
    @Override
    protected Session doReadSession(Serializable sessionId) {
        Session session = (Session) template.opsForValue().get(sessionId);
        return session;
    }

    // 更新session的最后一次访问时间
    @Override
    protected void doUpdate(Session session) {
        template.opsForValue().set(session.getId(), session, session.getTimeout(), TimeUnit.MILLISECONDS);
    }

    // 删除session
    @Override
    protected void doDelete(Session session) {
        template.opsForValue().getOperations().delete(session.getId());
    }

    //获取所有的session
    @Override
    public Collection<Session> getActiveSessions() {
        //获取redis中的所有session，大数据量时性能较低
        Set<String> keys = template.opsForValue().getOperations().keys("*");
//        List<Session> sessions = new ArrayList<>();
//        for (String key : keys) {
//            Session session = (Session) template.opsForValue().get(key);
//            sessions.add(session);
//        }
        return (List<Session>) template.opsForValue().multiGet(keys);
    }
}